<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Notifications\AfterSalesStatusChanged;

class AfterSalesRequest extends Model
{
    use HasFactory;

    protected $fillable = [
        'order_id',
        'user_id',
        'type',
        'reason',
        'description',
        'images',
        'status',
        'extended_status',
        'requested_amount',
        'approved_amount',
        'submitted_at',
        'approved_at',
        'rejected_at',
        'completed_at',
        'cancelled_at',
        'admin_comment',
        'rejection_reason',
    ];

    protected $casts = [
        'images' => 'array',
        'requested_amount' => 'decimal:2',
        'approved_amount' => 'decimal:2',
        'submitted_at' => 'datetime',
        'approved_at' => 'datetime',
        'rejected_at' => 'datetime',
        'completed_at' => 'datetime',
        'cancelled_at' => 'datetime',
    ];

    // 售后类型常量
    const TYPE_RETURN = 'return';      // 退货
    const TYPE_REFUND = 'refund';      // 退款
    const TYPE_EXCHANGE = 'exchange';  // 换货

    // 状态常量
    const STATUS_PENDING = 'pending';      // 待审核
    const STATUS_APPROVED = 'approved';    // 已通过
    const STATUS_REJECTED = 'rejected';    // 已拒绝
    const STATUS_PROCESSING = 'processing'; // 处理中
    const STATUS_COMPLETED = 'completed';   // 已完成
    const STATUS_CANCELLED = 'cancelled';   // 已取消

    // 扩展状态常量（用于换货流程）
    const EXTENDED_STATUS_RETURN_SHIPPED = 'return_shipped';     // 用户已寄回
    const EXTENDED_STATUS_RETURN_RECEIVED = 'return_received';   // 商家已收货
    const EXTENDED_STATUS_NEW_SENT = 'new_sent';                 // 新商品已寄出
    const EXTENDED_STATUS_NEW_DELIVERED = 'new_delivered';       // 新商品已送达

    /**
     * 关联订单
     */
    public function order(): BelongsTo
    {
        return $this->belongsTo(Order::class);
    }

    /**
     * 关联用户
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * 关联售后商品
     */
    public function items(): HasMany
    {
        return $this->hasMany(AfterSalesItem::class, 'request_id');
    }

    /**
     * 关联审批记录
     */
    public function approvals(): HasMany
    {
        return $this->hasMany(AfterSalesApproval::class, 'request_id');
    }

    /**
     * 关联物流信息
     */
    public function logistics(): HasMany
    {
        return $this->hasMany(AfterSalesLogistic::class, 'request_id');
    }

    /**
     * 获取售后类型文本
     */
    public function getTypeTextAttribute(): string
    {
        return match($this->type) {
            self::TYPE_RETURN => '退货',
            self::TYPE_REFUND => '退款',
            self::TYPE_EXCHANGE => '换货',
            default => '未知类型',
        };
    }

    /**
     * 获取状态文本
     */
    public function getStatusTextAttribute(): string
    {
        $baseStatus = match($this->status) {
            self::STATUS_PENDING => '待审核',
            self::STATUS_APPROVED => '已通过',
            self::STATUS_REJECTED => '已拒绝',
            self::STATUS_PROCESSING => '处理中',
            self::STATUS_COMPLETED => '已完成',
            self::STATUS_CANCELLED => '已取消',
            default => '未知状态',
        };

        // 如果有扩展状态，显示更详细的信息
        if ($this->status === self::STATUS_PROCESSING && $this->extended_status) {
            $extendedText = match($this->extended_status) {
                self::EXTENDED_STATUS_RETURN_SHIPPED => '用户已寄回',
                self::EXTENDED_STATUS_RETURN_RECEIVED => '商家已收货',
                self::EXTENDED_STATUS_NEW_SENT => '新商品已寄出',
                self::EXTENDED_STATUS_NEW_DELIVERED => '新商品已送达',
                default => '处理中',
            };
            return $extendedText;
        }

        return $baseStatus;
    }

    /**
     * 获取状态颜色
     */
    public function getStatusColorAttribute(): string
    {
        return match($this->status) {
            self::STATUS_PENDING => 'orange',
            self::STATUS_APPROVED => 'blue',
            self::STATUS_REJECTED => 'red',
            self::STATUS_PROCESSING => 'indigo',
            self::STATUS_COMPLETED => 'green',
            self::STATUS_CANCELLED => 'gray',
            default => 'gray',
        };
    }

    /**
     * 是否可以取消
     */
    public function canCancel(): bool
    {
        return in_array($this->status, [self::STATUS_PENDING, self::STATUS_APPROVED]);
    }

    /**
     * 是否可以编辑
     */
    public function canEdit(): bool
    {
        return $this->status === self::STATUS_PENDING;
    }

    /**
     * 更新状态并发送通知
     */
    private function updateStatusWithNotification(array $data): void
    {
        $this->update($data);
        
        // 发送通知
        $this->order->user->notify(new AfterSalesStatusChanged($this));
    }

    /**
     * 标记为已提交
     */
    public function markAsSubmitted(): void
    {
        $this->updateStatusWithNotification([
            'status' => self::STATUS_PENDING,
            'submitted_at' => now(),
        ]);
    }

    /**
     * 标记为已拒绝
     */
    public function markAsRejected(string $rejectionReason): void
    {
        $this->updateStatusWithNotification([
            'status' => self::STATUS_REJECTED,
            'rejection_reason' => $rejectionReason,
            'rejected_at' => now(),
        ]);
    }

    /**
     * 标记为处理中
     */
    public function markAsProcessing(): void
    {
        $this->updateStatusWithNotification([
            'status' => self::STATUS_PROCESSING,
        ]);
    }

    /**
     * 标记为已取消
     */
    public function markAsCancelled(): void
    {
        $this->updateStatusWithNotification([
            'status' => self::STATUS_CANCELLED,
            'cancelled_at' => now(),
        ]);
        
        // 更新关联订单的售后状态
        $this->order->updateAfterSalesStatus();
    }

    /**
     * 标记为已完成（重写以更新订单状态）
     */
    public function markAsCompleted(): void
    {
        $this->updateStatusWithNotification([
            'status' => self::STATUS_COMPLETED,
            'completed_at' => now(),
        ]);
        
        // 更新关联订单的售后状态
        $this->order->updateAfterSalesStatus();
    }

    /**
     * 标记为已通过（重写以更新订单状态）
     */
    public function markAsApproved(float $approvedAmount = null, string $adminComment = null): void
    {
        $this->updateStatusWithNotification([
            'status' => self::STATUS_APPROVED,
            'approved_amount' => $approvedAmount ?? $this->requested_amount,
            'admin_comment' => $adminComment,
            'approved_at' => now(),
        ]);
        
        // 更新关联订单的售后状态
        $this->order->updateAfterSalesStatus();
    }

    /**
     * 换货流程：用户已寄回商品
     */
    public function markReturnShipped(): void
    {
        if ($this->type !== self::TYPE_EXCHANGE) {
            throw new \Exception('只有换货申请才能标记为已寄回');
        }

        $this->updateStatusWithNotification([
            'status' => self::STATUS_PROCESSING,
            'extended_status' => self::EXTENDED_STATUS_RETURN_SHIPPED,
        ]);
    }

    /**
     * 换货流程：商家已收到原商品
     */
    public function markReturnReceived(): void
    {
        if ($this->type !== self::TYPE_EXCHANGE) {
            throw new \Exception('只有换货申请才能标记为已收货');
        }

        $this->updateStatusWithNotification([
            'status' => self::STATUS_PROCESSING,
            'extended_status' => self::EXTENDED_STATUS_RETURN_RECEIVED,
        ]);
    }

    /**
     * 换货流程：新商品已寄出
     */
    public function markNewSent(): void
    {
        if ($this->type !== self::TYPE_EXCHANGE) {
            throw new \Exception('只有换货申请才能标记为新商品已寄出');
        }

        $this->updateStatusWithNotification([
            'status' => self::STATUS_PROCESSING,
            'extended_status' => self::EXTENDED_STATUS_NEW_SENT,
        ]);
    }

    /**
     * 换货流程：新商品已送达
     */
    public function markNewDelivered(): void
    {
        if ($this->type !== self::TYPE_EXCHANGE) {
            throw new \Exception('只有换货申请才能标记为新商品已送达');
        }

        $this->updateStatusWithNotification([
            'status' => self::STATUS_PROCESSING,
            'extended_status' => self::EXTENDED_STATUS_NEW_DELIVERED,
        ]);
    }

    /**
     * 获取换货流程进度
     */
    public function getExchangeProgress(): array
    {
        if ($this->type !== self::TYPE_EXCHANGE) {
            return [];
        }

        $steps = [
            'return_shipped' => ['name' => '用户已寄回', 'completed' => false],
            'return_received' => ['name' => '商家已收货', 'completed' => false],
            'new_sent' => ['name' => '新商品已寄出', 'completed' => false],
            'new_delivered' => ['name' => '新商品已送达', 'completed' => false],
        ];

        if ($this->extended_status) {
            $currentStep = $this->extended_status;
            foreach ($steps as $step => $data) {
                $steps[$step]['completed'] = true;
                if ($step === $currentStep) {
                    break;
                }
            }
        }

        return $steps;
    }

    /**
     * 检查是否接近超时
     */
    public function isNearTimeout(int $warningDays = 5): bool
    {
        if ($this->extended_status !== self::EXTENDED_STATUS_NEW_SENT) {
            return false;
        }

        $adminLogistics = $this->getAdminSendLogistics()
            ->where('status', 'shipped')
            ->first();

        if (!$adminLogistics || !$adminLogistics->sent_at) {
            return false;
        }

        $sentDate = \Carbon\Carbon::parse($adminLogistics->sent_at);
        $daysDiff = $sentDate->diffInDays(now());

        return $daysDiff >= $warningDays;
    }

    /**
     * 获取超时提醒消息
     */
    public function getTimeoutMessage(?int $autoConfirmDays = null): string
    {
        if ($this->extended_status !== self::EXTENDED_STATUS_NEW_SENT) {
            return '';
        }

        // 从系统设置读取超时天数
        if ($autoConfirmDays === null) {
            $autoConfirmDays = (int) SystemSetting::get('exchange_delivery_timeout_days', 7);
        }

        $adminLogistics = $this->getAdminSendLogistics()
            ->where('status', 'shipped')
            ->first();

        if (!$adminLogistics || !$adminLogistics->sent_at) {
            return '';
        }

        $sentDate = \Carbon\Carbon::parse($adminLogistics->sent_at);
        $daysDiff = $sentDate->diffInDays(now());

        if ($daysDiff >= $autoConfirmDays) {
            return "已超时{$daysDiff}天，系统将自动确认";
        } elseif ($daysDiff >= 5) {
            $remainingDays = $autoConfirmDays - $daysDiff;
            return "还有{$remainingDays}天将自动确认";
        }

        return '';
    }

    /**
     * 获取用户寄回的物流信息
     */
    public function getUserReturnLogistics()
    {
        return $this->logistics()
            ->where('submitted_by', AfterSalesLogistic::SUBMITTED_BY_USER)
            ->where('type', AfterSalesLogistic::TYPE_RETURN)
            ->get();
    }

    /**
     * 获取商家寄出的物流信息
     */
    public function getAdminSendLogistics()
    {
        return $this->logistics()
            ->where('submitted_by', AfterSalesLogistic::SUBMITTED_BY_ADMIN)
            ->where('type', AfterSalesLogistic::TYPE_EXCHANGE)
            ->get();
    }

    /**
     * 检查是否有用户寄回的物流信息
     */
    public function hasUserReturnLogistics(): bool
    {
        return $this->getUserReturnLogistics()->count() > 0;
    }

    /**
     * 检查是否有商家寄出的物流信息
     */
    public function hasAdminSendLogistics(): bool
    {
        return $this->getAdminSendLogistics()->count() > 0;
    }

    /**
     * 自动更新换货状态（基于物流信息）
     */
    public function updateExchangeStatusFromLogistics(): void
    {
        if ($this->type !== self::TYPE_EXCHANGE) {
            return;
        }

        $userReturnLogistics = $this->getUserReturnLogistics();
        $adminSendLogistics = $this->getAdminSendLogistics();

        // 如果用户已寄回，但状态不是 return_shipped
        if ($userReturnLogistics->count() > 0 && $this->extended_status !== self::EXTENDED_STATUS_RETURN_SHIPPED) {
            $this->markReturnShipped();
        }

        // 如果商家已寄出，但状态不是 new_sent
        if ($adminSendLogistics->count() > 0 && $this->extended_status !== self::EXTENDED_STATUS_NEW_SENT) {
            $this->markNewSent();
        }
    }
}
